package com.ruoyi.system.service.impl.fxImpl;

import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.dto.FxGoodPurchaseDto;
import com.ruoyi.system.domain.dto.FxOrderDto;
import com.ruoyi.system.domain.dto.GoodInventoryDto;
import com.ruoyi.system.domain.fx.*;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.mapper.fx.*;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.fx.IFxGoodPurchaseService;
import com.ruoyi.system.service.fx.IFxOrderItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.PageUtils.startPage;


/**
 * 商品采购
 * Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-23
 */
@Service
public class FxGoodPurchaseServiceImpl implements IFxGoodPurchaseService {
    @Autowired
    private FxGoodPurchaseMapper fxGoodPurchaseMapper;
    @Autowired
    private FxSupplierGoodMapper fxSupplierGoodMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IFxOrderItemService orderItemService;
    @Autowired
    private FxOrderMapper fxOrderMapper;
    @Autowired
    private FxUserMapper fxUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private FxStoreMapper fxStoreMapper;
    @Autowired
    private FxToJoinMapper fxToJoinMapper;

    /**
     * 查询商品采购
     *
     * @param id 商品采购主键
     * @return 商品采购
     */
    @Override
    public FxGoodPurchase selectFxGoodPurchaseById(Long id) {
        return fxGoodPurchaseMapper.selectFxGoodPurchaseById(id);
    }

    /**
     * 查询商品采购列表
     *
     * @param fxGoodPurchase 商品采购
     * @return 商品采购
     */
    @Override
    public List<FxGoodPurchase> selectFxGoodPurchaseList(FxGoodPurchase fxGoodPurchase) {
        List<FxGoodPurchase> goodPurchaseList = new ArrayList<>();
        Long userId = SecurityUtils.getUserId();
        FxUser fxUser = new FxUser();
        fxUser.setSysUserid(userId);
        List<FxUser> userList = fxUserMapper.selectFxUserList(fxUser);
        List<Integer> role = sysUserRoleMapper.selectByUserId(userId);
        // 判断是否是超级管理员
        fxGoodPurchase.setStatus(1);
        if (StringUtils.isNotEmpty(userList)) {
            Long roleId = userList.get(0).getRoleType();
            if (roleId != null && roleId == 3L) //为3是供应商
                return new ArrayList<>();
            if (StringUtils.isNotEmpty(role) && !role.contains(1)) {// 超级管理员 可以查看全部
                fxGoodPurchase.setStoreId(userList.get(0).getStoreId());
            }
        }
        startPage();
        goodPurchaseList = fxGoodPurchaseMapper.selectFxGoodPurchaseListByGoodName(fxGoodPurchase); // 全部采购列表
        List<Long> ids = goodPurchaseList.stream().map(FxGoodPurchase::getGoodId).collect(Collectors.toList());
        if(!ids.isEmpty()){
            fxGoodPurchase.setGoodIds(ids.toArray(new Long[ids.size()]));
            List<FxGoodPurchase> list = fxGoodPurchaseMapper.selectFxGoodSonPurchaseListByGoodName(fxGoodPurchase);
            goodPurchaseList.addAll(list);
        }
        if (goodPurchaseList.size() == 0) {
            return new ArrayList<>();
        }
        List<Long> goodIdList = goodPurchaseList
                .stream().map(FxGoodPurchase::getGoodId)
                .distinct().collect(Collectors.toList()); // 拿商品id
        List<FxSupplierGood> supplierGoodList = fxSupplierGoodMapper.selectFxSupplierGoodListByGoodIds(goodIdList); // 拿商品详细信息
        Map<Long, FxSupplierGood> supplierGoodMap = supplierGoodList.stream()
                .collect(Collectors.toMap(FxSupplierGood::getId,supplier -> supplier)); // 转map
        List<Integer> storeIdList = goodPurchaseList.stream()
                .map(FxGoodPurchase::getStoreId)
                .distinct()
                .map(Long::intValue).collect(Collectors.toList()); // 拿到 门店id 并转换
        List<FxStore> fxStoreList = fxStoreMapper.selectFxStoreListByIds(storeIdList); // 查询全部门店
        Map<Long, FxStore> storeMap = fxStoreList.stream().collect(Collectors.toMap(FxStore::getId, store -> store)); // 转换为 map
        fxUser.setSysUserid(null);
        fxUser.setRoleType(4L); // 只查询店铺
        List<FxUser> fxUserList = fxUserMapper.selectFxUserList(fxUser);
        Map<Long, FxUser> userMap =  fxUserList.stream().collect(Collectors.toMap(FxUser::getSysUserid, user -> user));
        goodPurchaseList.forEach(purchase -> {
            FxStore fxStore = storeMap.get(purchase.getStoreId());
            FxSupplierGood supplierGood = supplierGoodMap.get(purchase.getGoodId()); // 拿到对应商品详情
            FxUser user = userMap.get(purchase.getCreateUser());
            FxToJoin fxToJoin = fxToJoinMapper.selectFxToJoinById(supplierGood.getSupplierId());
            if (StringUtils.isNotNull(fxToJoin))
                purchase.setCreaterName(fxToJoin.getStoreName());
            purchase.setGoodName(supplierGood == null ? "未知商品" : supplierGood.getGoodName()); // 设入 商品名
            purchase.setStoreName(fxStore == null ? "未知店铺" : fxStore.getStoreName()); // 设入 店铺名称
            purchase.setCreateUserName(user == null ? "未知人员" : user.getUserName()); // 设入 创建者姓名
        });
        return goodPurchaseList;
    }

    /**
     * 新增商品采购
     *
     * @param fxGoodPurchase 商品采购
     * @return 结果
     */
    @Override
    public int insertFxGoodPurchase(FxGoodPurchase fxGoodPurchase) {
        fxGoodPurchase.setCreateTime(DateUtils.getNowDate());
        return fxGoodPurchaseMapper.insertFxGoodPurchase(fxGoodPurchase);
    }

    /**
     * 批量采购
     *
     * @param fxGoodPurchaseDto
     * @return
     */
    @Override
    @Transactional
    public int insertMultiGoodPurchase(FxGoodPurchaseDto fxGoodPurchaseDto) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<Long> rolesList = loginUser.getUser().getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList());
        Long userId = fxGoodPurchaseDto.getCreateUser();
        FxUser fxUser = fxUserMapper.selectFxUserByUserId(userId);
        if (rolesList.contains(1L) || rolesList.contains(6L) || !rolesList.contains(4L)) {
            throw new GlobalException("该用户无法采购");
        } else{
            fxGoodPurchaseDto.setStoreId(fxUser.getStoreId());
        }
        Long[] goodIds = Convert.toLongArray(fxGoodPurchaseDto.getGoodIds());
        List<FxGoodPurchase> fxGoodPurchaseList = new ArrayList<>();
        List<FxGoodPurchase> nowList = new ArrayList<>();
        for (Long goodId : goodIds) {
            FxGoodPurchase fxGoodPurchase = new FxGoodPurchase();
            fxGoodPurchase.setGoodId(goodId);
            fxGoodPurchase.setCreateTime(DateUtils.getNowDate());
            fxGoodPurchase.setCreateUser(fxGoodPurchaseDto.getCreateUser());
            fxGoodPurchase.setRemark(fxGoodPurchaseDto.getRemark());
            fxGoodPurchase.setCounts(fxGoodPurchaseDto.getCounts());
            fxGoodPurchase.setStoreId(fxGoodPurchaseDto.getStoreId());
            fxGoodPurchaseList.add(fxGoodPurchase);
        }
        // 拿到采购清单 准备插入采购表
        // 判断采购表中 是否当前门店，有重复商品 有重复商品叠加数量
        fxGoodPurchaseDto.setGoodArr(goodIds);
        List<FxGoodPurchase> purchaseList = fxGoodPurchaseMapper.selectAllByStoreIdAndGoodId(fxGoodPurchaseDto);
        int result = 0;
        nowList = fxGoodPurchaseList;
        if (StringUtils.isNotEmpty(purchaseList) && StringUtils.isNotEmpty(fxGoodPurchaseList)) {
            Map<Long, FxGoodPurchase> map = fxGoodPurchaseList.stream().collect(Collectors.toMap(FxGoodPurchase::getGoodId, g->g));

            for (FxGoodPurchase purchase : purchaseList) {
                if (map.containsKey(purchase.getGoodId())) {
                    FxGoodPurchase f = map.get(purchase.getGoodId());
                    map.remove(purchase.getGoodId());
                    FxGoodPurchase fp = new FxGoodPurchase();
                    fp.setId(purchase.getId());
                    fp.setCounts(f.getCounts() + purchase.getCounts());
                    result += fxGoodPurchaseMapper.updateFxGoodPurchase(fp);
                }
            }
            nowList = new ArrayList<>(map.values());
        }
        if (StringUtils.isNotEmpty(nowList)) {
            result += fxGoodPurchaseMapper.insertBatch(nowList);
        }
        return result;
    }

    /**
     * 确认采购
     *
     * @param fxGoodPurchaseDto
     * @return
     */
    @Override
    @Transactional
    public int insertPurchase(FxGoodPurchaseDto fxGoodPurchaseDto) {
        // 初建 order对象
        FxOrderDto fxOrderDto = new FxOrderDto();
        // 拿到当前登录人 id
        Long userId = SecurityUtils.getUserId();
        // 查询当前登录人基本信息
        SysUser user = sysUserService.selectUserById(userId);
        // 插入下单人基本信息
        fxOrderDto.setUserId(userId);
        fxOrderDto.setUserName(user.getNickName());
        fxOrderDto.setPhoneNumber(user.getPhonenumber());
        // 生成订单号
        String orderId = System.currentTimeMillis() + "" + new Random().nextInt(10000);
        fxOrderDto.setId(orderId);
        // 插入订单状态 及 下单时间
        fxOrderDto.setOrderStatus(OrderStatus.待发货.getCode());
        fxOrderDto.setCreateTime(DateUtils.getNowDate());

        // 填充收货人信息 判断地址是否选择
        List<String> receiveList = new ArrayList<>();
        receiveList.add(fxGoodPurchaseDto.getReceiveName());
        receiveList.add(fxGoodPurchaseDto.getReceiveAddress());
        receiveList.add(fxGoodPurchaseDto.getReceivePhonenum());
        receiveList.add(fxGoodPurchaseDto.getReceiveLatitude());
        receiveList.add(fxGoodPurchaseDto.getReceiveLongitude());
        boolean receive = receiveList.stream().allMatch(r -> r != null && !r.trim().isEmpty()); // 判断是否有空值
        if (!receive) {
            throw new GlobalException("配送地址有误！");
        }

        fxOrderDto.setReceiveName(fxGoodPurchaseDto.getReceiveName()); // 收货人名称
        fxOrderDto.setReceiveAddress(fxGoodPurchaseDto.getReceiveAddress()); // 收货人地址
        fxOrderDto.setReceivePhonenum(fxGoodPurchaseDto.getReceivePhonenum()); // 收货人电话
        fxOrderDto.setReceiveLatitude(fxGoodPurchaseDto.getReceiveLatitude()); // 收货地址纬度
        fxOrderDto.setReceiveLongitude(fxGoodPurchaseDto.getReceiveLongitude()); // 收货地址经度

        fxOrderDto.setRegionId(fxGoodPurchaseDto.getRegionId()); // 区域id
        fxOrderDto.setRegionName(fxGoodPurchaseDto.getRegionName()); // 区域名称
        fxOrderDto.setStoreId(fxGoodPurchaseDto.getStoreId()); // 店铺id
        fxOrderDto.setStoreName(fxGoodPurchaseDto.getStoreName()); // 店铺名称
        fxOrderDto.setPayMoney(fxGoodPurchaseDto.getPayMoney()); // 总金额 付款金额
        fxOrderDto.setOrderType(fxGoodPurchaseDto.getOrderType()); // 订单类型（1店铺，2门店）
        fxOrderDto.setRemark(fxGoodPurchaseDto.getRemark()); // 描述备注
        fxOrderDto.setDeliveryType(fxGoodPurchaseDto.getDeliveryType()); // 配送方式 （1普通， 2加急）
        fxOrderDto.setDeliveryCost(fxGoodPurchaseDto.getDeliveryCost()); // 配送费用
        // 判断 是否选中采购
        List<FxGoodPurchase> goodPurchaseList = fxGoodPurchaseDto.getPurchaseList();
        if (!CollectionUtils.isEmpty(goodPurchaseList)) {
            Map<Long, FxGoodPurchase> goodMap = goodPurchaseList.stream().collect(Collectors.toMap(FxGoodPurchase::getGoodId, g -> g));
            Set<Long> ids = goodPurchaseList.stream().map(FxGoodPurchase::getId).collect(Collectors.toSet());
            fxGoodPurchaseMapper.updatePurchaseStatus(ids);
            // 拿到全部 商品id
            List<Long> goodIds = goodPurchaseList.stream().map(FxGoodPurchase::getGoodId).distinct().collect(Collectors.toList());
            // 拿到全部 商品
            List<FxSupplierGood> goodList = fxSupplierGoodMapper.selectFxSupplierGoodListByGoodIds(goodIds);
            // 准备插入订单
            for (FxSupplierGood supplierGood : goodList) {
                FxGoodPurchase fxGoodPurchase = goodMap.get(supplierGood.getId());
                Long goodId = fxGoodPurchase.getGoodId();
                if (Objects.equals(goodId, supplierGood.getId())) {
                    FxOrderItem orderItem = new FxOrderItem();
                    orderItem.setGoodTypeId(supplierGood.getClassTwoId());
                    orderItem.setGoodTypeName(supplierGood.getClassTwoName());
                    orderItem.setSupplierGoodId(supplierGood.getId());
                    orderItem.setGoodPrice(supplierGood.getTradePrice());
                    String counts = String.valueOf(fxGoodPurchase.getCounts());
                    orderItem.setGoodCount(counts);
                    // 插入订单 去修改 供应商商品库存
                    updateInventoryRecursive(goodId, Integer.parseInt(counts), supplierGood.getGoodName(), 3, 1);
                    orderItem.setOrderId(orderId);
                    orderItemService.insertFxOrderItem(orderItem);
                }
            }
        }
        return fxOrderMapper.insertFxOrder(fxOrderDto);
    }

    /**
     * 修改库存
     *
     * @param goodId      商品id
     * @param goodCount   商品数量
     * @param goodName    商品名称
     * @param retriesLeft 递归次数
     * @param handle      处理类型 （1下单 ， 2退单）
     */
    @Transactional
    public void updateInventoryRecursive(Long goodId, int goodCount, String goodName, int retriesLeft, int handle) {
        // 查询商品库存
        FxSupplierGood goodInventory = fxSupplierGoodMapper.selectFxSupplierGoodById(goodId);
        int counts = Math.toIntExact(goodInventory.getCounts()); // 数据库库存
        int sellCounts = Math.toIntExact(goodInventory.getTotalSellCount()); //总销售数量
        if (handle == 1) {
            // 判断库存是否足够
            if (counts < goodCount) {
                throw new GlobalException(goodName + "库存不足");
            }
            // 计算新的库存
            counts = counts - goodCount;
            sellCounts = sellCounts + goodCount;
        }
        if (handle == 2) {
            // 计算新的库存
            counts = counts + goodCount;
            sellCounts = sellCounts - goodCount;
        }
        // 准备更新库存
        GoodInventoryDto goodInventoryDto = new GoodInventoryDto();
        goodInventoryDto.setGoodId(goodInventory.getId());
        goodInventoryDto.setCounts(counts);
        goodInventoryDto.setTotalSellCount(sellCounts);
        goodInventoryDto.setVersion(goodInventory.getVersion());
        // 更新库存
        int update = fxSupplierGoodMapper.updateGoodInventory(goodInventoryDto);
        // 如果更新失败并且还有重试次数，重新尝试更新
        if (update == 0 && retriesLeft >= 1) {
            updateInventoryRecursive(goodId, goodCount, goodName, retriesLeft - 1, handle);
        } else if (update == 0 && handle == 1) {
            // 如果更新失败且没有重试次数了，处理最终的失败情况
            throw new GlobalException(goodName + "库存不足");
        } else if (update == 0 && handle == 2) {
            throw new GlobalException("操作失败！");
        }
    }

    /**
     * 修改商品采购
     *
     * @param fxGoodPurchase 商品采购
     * @return 结果
     */
    @Override
    public int updateFxGoodPurchase(FxGoodPurchase fxGoodPurchase) {
        return fxGoodPurchaseMapper.updateFxGoodPurchase(fxGoodPurchase);
    }

    /**
     * 批量删除商品采购
     *
     * @param ids 需要删除的商品采购主键
     * @return 结果
     */
    @Override
    public int deleteFxGoodPurchaseByIds(Long[] ids) {
        return fxGoodPurchaseMapper.deleteFxGoodPurchaseByIds(ids);
    }

    /**
     * 删除商品采购信息
     *
     * @param id 商品采购主键
     * @return 结果
     */
    @Override
    public int deleteFxGoodPurchaseById(Long id) {
        return fxGoodPurchaseMapper.deleteFxGoodPurchaseById(id);
    }

    @Override
    public int selectFxGoodPurchaseListCount(FxGoodPurchase fxGoodPurchase) {
        return fxGoodPurchaseMapper.selectFxGoodPurchaseListCount(fxGoodPurchase);
    }
}
